package core;


import static org.junit.Assert.*;
import core.ItemManager;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.Set;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class CoreFacadeTests {

	CoreFacade core = CoreFacade.getInstance();
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
	}

	@AfterClass
	public static void tearDownAfterClass() throws Exception {
	}

	@Before
	public void setUp() throws Exception {
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testDataPersistence()
	{
		ItemManager im = ItemManager.getInstance();
		CoreFacade core = CoreFacade.getInstance();
		try{
			StorageUnit su1 = core.addStorageUnit("StorageUnit1");
			StorageUnit su2 = core.addStorageUnit("StorageUnit2");
			ProductGroup pg1 = core.addProductGroup(su1, "PG1", 2, Unit.count);
			Product p1 = new Product(Calendar.getInstance(), new Barcode("test"), "Product one", new Amount(Unit.count,2),3,3);
		
		Calendar date = new GregorianCalendar();
		Item i = new Item(p1,pg1,date,im.generateBarcode());
		try {
			core.addProduct(p1, pg1);
			core.addItem(i, su1, 0, false);
			core.saveData();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try {
			Set<Item> setPG1 = core.getAllItems(pg1);
			assertTrue(setPG1.size()==1);
			Collection<Item> setAll = core.getAllItemsInRoot();
			assertTrue(setAll.size()==1);
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try {
			core.removeItem(i);
			//core.removeItem(i.getBarcodeString());
			Collection<Item> setAll = core.getAllItemsInRoot();
			//assertTrue(setAll.size()==0);
			
			core.loadDataFromMemory();
			
			setAll = core.getAllItemsInRoot();
			assertTrue(setAll.size()==0);
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		}
		catch(Exception e)
		{
			
		}
		
		
		
		
	}
	
	@Test
	public void transferProductTest() throws Exception
	{
		StorageUnit unit1 = core.addStorageUnit("unit1");
		StorageUnit unit2 = core.addStorageUnit("unit2");
		Amount amount1 = new Amount(Unit.count, 5);
		ProductGroup group1 = core.addProductGroup(unit1, "group1", 1, Unit.count);
		ProductGroup group2 =  core.addProductGroup(unit2, "group2", 1, Unit.count);
		Barcode prodBCode = new Barcode("12345");
		Amount prodAmount = new Amount(Unit.count, 15);
		Calendar cal = new GregorianCalendar();
		Product prod1 = new Product(cal, prodBCode, "FoodItems", prodAmount, 3, 6);
		ItemManager im = ItemManager.getInstance();
		try
		{
			core.addProduct(prod1, unit1);
			assertTrue(core.getAllProducts(unit1).contains(prod1));
			// test transfer in same storage unit, no items
			core.transferProduct(prod1, unit1, group1);
			// product should be in new container
			assertFalse(core.getAllProducts(unit1).contains(prod1));
			// product should NOT be in old container
			assertTrue(core.getAllProducts(group1).contains(prod1));
			
			// test transfer from one storage unit into another storage unit
			core.transferProduct(prod1, group1, unit2);
			// product should now be in new unit2
			assertTrue(core.getAllProducts(unit2).contains(prod1));
			// product should also still be in unit1
			assertTrue(core.getAllProducts(group1).contains(prod1));
			
			Item item1 = new Item(prod1, unit1,new GregorianCalendar(), im.generateBarcode());
			core.addItem(item1, unit1,0, false);
			// add item into unit1;
			assertTrue(core.getAllItems(group1).contains(item1));
			//core.addItem(prod1.getBarcodeString(), new GregorianCalendar(), 2, unit1);
			// transfer product and items from unit1 to unit1:group1
			core.transferProduct(prod1, group1, unit1);
			//Set<Item> items = core.getAllItems(group1);
			// group1 should have items in it
			assertTrue(core.getAllItems(group1).isEmpty());
			// unit 1 shouldn't have any items left
			assertFalse(core.getAllItems(unit1).isEmpty());
			
			// now check moving into new StorageUnit
			// move product into unit2
			core.transferProduct(prod1, unit1, unit2);
			// items should remain in group1
			assertFalse(core.getAllItems(unit1).isEmpty());
			assertTrue(core.getAllItems(group1).isEmpty());
			
			
			
		} catch (Exception e)
		{
			System.out.println(e.getMessage());

			e.printStackTrace();
			fail();
		}
		
	}
	
	@Test
	public void canDeleteProductTest() throws Exception
	{
		StorageUnit unit1 = core.addStorageUnit("unit3");
		//StorageUnit unit2 = core.addStorageUnit("unit2");
		Amount amont1 = new Amount(Unit.count, 5);
		//ProductGroup group1 = core.addProductGroup(unit1, "group1", 1, Unit.count);
		// group2 =  core.addProductGroup(unit2, "group2", 1, Unit.count);
		Barcode prodBCode = new Barcode("12345");
		Amount prodAmount = new Amount(Unit.count, 15);
		Calendar cal = new GregorianCalendar();
		Product prod1 = new Product(cal, prodBCode, "FoodItems", prodAmount, 3, 6);
		
		Barcode prodBCode2 = new Barcode("123456789");
		Product prod2 = new Product(cal, prodBCode2, "FoodItemdsds", prodAmount, 3, 6);
		
		core.addProduct(prod2, unit1);
		
		assertFalse (core.canDeleteProduct(prod1));
		assertTrue (core.canDeleteProduct(prod2));
		
		
	}
}
